package com.cgtong.android;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.multidex.MultiDex;
import android.view.Gravity;

import com.baidu.mapapi.SDKInitializer;
import com.blankj.utilcode.util.CrashUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.blankj.utilcode.util.Utils;
import com.cgtong.android.callback.CustomCallback;
import com.cgtong.android.callback.EmptyCallback;
import com.cgtong.android.callback.ErrorCallback;
import com.cgtong.android.callback.LoadingCallback;
import com.cgtong.android.callback.TimeoutCallback;
import com.cgtong.android.db.UserAccount;
import com.cgtong.android.http.ApiManager;
import com.cgtong.android.http.ConstantManager;
import com.cgtong.android.http.TokenInterceptor;
import com.cgtong.android.service.LocationService;
import com.kingja.loadsir.core.LoadSir;
import com.squareup.leakcanary.LeakCanary;
import com.zhouyou.http.EasyHttp;
import com.zhouyou.http.cache.converter.SerializableDiskConverter;
import com.zhouyou.http.cache.model.CacheMode;
import com.zhouyou.http.cookie.CookieManger;

import org.litepal.LitePal;
import org.litepal.LitePalApplication;
import org.litepal.crud.DataSupport;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by zhuqingchun
 * 2017/9/30 09:41.
 */

public class App extends LitePalApplication {

    private static App sInstance = null;
    private LocationService locationService;

    public static App getInstance() {
        return sInstance;
    }

    /**
     * 维护Activity 的list
     */
    private static List<Activity> mActivitys = Collections
            .synchronizedList(new LinkedList<Activity>());

    @Override
    public void onCreate() {
        super.onCreate();
        sInstance = this;
        initBaiduLocService();
        initHttp();
        initLoadSir();
        LitePal.initialize(this);
        Utils.init(this);
        CrashUtils.init();
        initLogUtil();
        registerActivityListener();
        //设置全部toast显示在屏幕中间
        ToastUtils.setGravity(Gravity.CENTER,0,0);
    }

    private void initLogUtil() {
        LogUtils.getConfig().setLogSwitch(BuildConfig.DEBUG)
                .setBorderSwitch(false);
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    private void initLeakCanary() {
        if (LeakCanary.isInAnalyzerProcess(this)) {
            return;
        }
        LeakCanary.install(this);
    }

    /***
     * 初始化定位sdk
     */
    private void initBaiduLocService() {
        locationService = new LocationService(getApplicationContext());
        SDKInitializer.initialize(getApplicationContext());
    }

    private void initLoadSir() {
        LoadSir.beginBuilder()
                .addCallback(new ErrorCallback())
                .addCallback(new EmptyCallback())
                .addCallback(new LoadingCallback())
                .addCallback(new TimeoutCallback())
                .addCallback(new CustomCallback())
                .setDefaultCallback(LoadingCallback.class)
                .commit();
    }

    private void initHttp() {
        EasyHttp.init(this);//默认初始化,必须调用
        //全局设置请求参数
//        HttpParams params = new HttpParams();
//        params.put("appId", ApiManager.APPID);

        //以下设置的所有参数是全局参数,同样的参数可以在请求的时候再设置一遍,那么对于该请求来讲,请求中的参数会覆盖全局参数
        EasyHttp.getInstance()
                //可以全局统一设置全局URL
                .setBaseUrl(ApiManager.BASE_URL)//设置全局URL
                .setCookieStore(new CookieManger(this))////支持添加Cookie
                // 打开该调试开关并设置TAG,不需要就不要加入该行
                // 最后的true表示是否打印内部异常，一般打开方便调试错误
                .debug("EasyHttp", BuildConfig.DEBUG)
                //如果使用默认的60秒,以下三行也不需要设置
                .setReadTimeOut(60 * 1000)
                .setWriteTimeOut(60 * 100)
                .setConnectTimeout(60 * 100)
                //可以全局统一设置超时重连次数,默认为3次,那么最差的情况会请求4次(一次原始请求,三次重连请求),
                //不需要可以设置为0
                .setRetryCount(3)//网络不好自动重试3次
                //可以全局统一设置超时重试间隔时间,默认为500ms,不需要可以设置为0
                .setRetryDelay(500)//每次延时500ms重试
                //可以全局统一设置超时重试间隔叠加时间,默认为0ms不叠加
                .setRetryIncreaseDelay(500)//每次延时叠加500ms
                //可以全局统一设置缓存模式,默认是不使用缓存,可以不传,具体请看CacheMode
                .setCacheMode(CacheMode.NO_CACHE)
                //可以全局统一设置缓存时间,默认永不过期
                .setCacheTime(-1)//-1表示永久缓存,单位:秒 ，Okhttp和自定义RxCache缓存都起作用
                //全局设置自定义缓存保存转换器，主要针对自定义RxCache缓存
                .setCacheDiskConverter(new SerializableDiskConverter())//默认缓存使用序列化转化
                //全局设置自定义缓存大小，默认50M
                .setCacheMaxSize(100 * 1024 * 1024)//设置缓存大小为100M
                //设置缓存版本，如果缓存有变化，修改版本后，缓存就不会被加载。特别是用于版本重大升级时缓存不能使用的情况
                .setCacheVersion(1)//缓存版本为1
                //可以设置https的证书,以下几种方案根据需要自己设置
                .setCertificates()                                  //方法一：信任所有证书,不安全有风险
//                .addCommonParams(params)//设置全局公共参数
                .addInterceptor(new TokenInterceptor());
    }


    /**
     * 注册生命周期回调
     */
    private void registerActivityListener() {
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                /*
                 *  监听到 Activity创建事件 将该 Activity 加入list
                 */
                pushActivity(activity);
//                LogUtils.d("onActivityCreated:" + activity.getClass().getSimpleName());
            }

            @Override
            public void onActivityStarted(Activity activity) {
//                LogUtils.d("onActivityStarted:" + activity.getClass().getSimpleName());

            }

            @Override
            public void onActivityResumed(Activity activity) {
//                LogUtils.d("onActivityResumed:" + activity.getClass().getSimpleName());

            }

            @Override
            public void onActivityPaused(Activity activity) {
//                LogUtils.d("onActivityPaused:" + activity.getClass().getSimpleName());

            }

            @Override
            public void onActivityStopped(Activity activity) {
//                LogUtils.d("onActivityStopped:" + activity.getClass().getSimpleName());

            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
//                LogUtils.d("onActivitySaveInstanceState:" + activity.getClass().getSimpleName());

            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                if (null == mActivitys && mActivitys.isEmpty()) {
                    return;
                }
                if (mActivitys.contains(activity)) {
//                    LogUtils.d("onActivityDestroyed:" + activity.getClass().getSimpleName());

                    /**
                     *  监听到 Activity销毁事件 将该Activity 从list中移除
                     */
                    popActivity(activity);
                }
            }
        });
    }

    /**
     * @param activity 作用说明 ：添加一个activity到管理里
     */
    public void pushActivity(Activity activity) {
        mActivitys.add(activity);
        LogUtils.d("activityList:size:" + mActivitys.size());
    }

    /**
     * @param activity 作用说明 ：删除一个activity在管理里
     */
    public void popActivity(Activity activity) {
        mActivitys.remove(activity);
        LogUtils.d("activityList:size:" + mActivitys.size());
    }


    /**
     * get current Activity 获取当前Activity（栈中最后一个压入的）
     */
    public static Activity currentActivity() {
        if (mActivitys == null || mActivitys.isEmpty()) {
            return null;
        }
        Activity activity = mActivitys.get(mActivitys.size() - 1);
        return activity;
    }

    /**
     * 结束当前Activity（栈中最后一个压入的）
     */
    public static void finishCurrentActivity() {
        if (mActivitys == null || mActivitys.isEmpty()) {
            return;
        }
        Activity activity = mActivitys.get(mActivitys.size() - 1);
        finishActivity(activity);
    }

    /**
     * 结束指定的Activity
     */
    public static void finishActivity(Activity activity) {
        if (mActivitys == null || mActivitys.isEmpty()) {
            return;
        }
        if (activity != null) {
            mActivitys.remove(activity);
            activity.finish();
            activity = null;
        }
    }

    /**
     * 结束指定类名的Activity
     */
    public static void finishActivity(Class<?> cls) {
        if (mActivitys == null || mActivitys.isEmpty()) {
            return;
        }
        for (Activity activity : mActivitys) {
            if (activity.getClass().equals(cls)) {
                finishActivity(activity);
            }
        }
    }

    /**
     * 按照指定类名找到activity
     */
    public static Activity findActivity(Class<?> cls) {
        Activity targetActivity = null;
        if (mActivitys != null) {
            for (Activity activity : mActivitys) {
                if (activity.getClass().equals(cls)) {
                    targetActivity = activity;
                    break;
                }
            }
        }
        return targetActivity;
    }

    /**
     * @return 作用说明 ：获取当前最顶部activity的实例
     */
    public Activity getTopActivity() {
        Activity mBaseActivity = null;
        synchronized (mActivitys) {
            final int size = mActivitys.size() - 1;
            if (size < 0) {
                return null;
            }
            mBaseActivity = mActivitys.get(size);
        }
        return mBaseActivity;

    }

    /**
     * @return 作用说明 ：获取当前最顶部的acitivity 名字
     */
    public String getTopActivityName() {
        Activity mBaseActivity = null;
        synchronized (mActivitys) {
            final int size = mActivitys.size() - 1;
            if (size < 0) {
                return null;
            }
            mBaseActivity = mActivitys.get(size);
        }
        return mBaseActivity.getClass().getName();
    }

    /**
     * 结束所有Activity
     */
    public void finishAllActivity() {
        if (mActivitys == null) {
            return;
        }
        for (Activity activity : mActivitys) {
            activity.finish();
        }
        mActivitys.clear();
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        finishAllActivity();
    }

    public LocationService getLocationService() {
        return locationService;
    }

    /**
     * 是否有用户登录
     *
     * @return
     */
    public synchronized boolean isUserLogin() {
        return DataSupport.where(" loginStatus = ? ", String.valueOf(ConstantManager.LOGIN_IN)).find(UserAccount.class).size() > 0;
    }

    /**
     * 修改用户
     *
     * @param userAccount
     */
    public synchronized boolean updateAccount(UserAccount userAccount) {
        UserAccount userFromDb = findAccountByUserId(String.valueOf(userAccount.getUserId()));
        if (null != userFromDb) {//exists
            userAccount.setId(userFromDb.getId());
        }
        if (userAccount.update(userAccount.getId()) > 0) {
            return true;
        }
        return false;
    }

    /**
     * 获取当前登录用户
     *
     * @return
     */
    public synchronized UserAccount getCurrentAccount() {
        List<UserAccount> userAccounts = DataSupport.where(" loginStatus = ? ", String.valueOf(ConstantManager.LOGIN_IN)).find(UserAccount.class);
        if (null == userAccounts || userAccounts.size() == 0) {
            return null;
        }
        return userAccounts.get(0);
    }

    /**
     * 判断是否是当前用户自己
     * @param userId
     * @return
     */
    public  boolean isOwnself(long userId) {
        List<UserAccount> userAccounts = DataSupport.where(" loginStatus = ? ", String.valueOf(ConstantManager.LOGIN_IN)).find(UserAccount.class);
        if (null == userAccounts || userAccounts.size() == 0) {
            return false;
        }
        return userAccounts.get(0).getUserId() == userId;
    }

    /**
     * 获取用户Token
     *
     * @return
     */
    public synchronized String getUserToken() {
        List<UserAccount> userAccounts = DataSupport.where(" loginStatus = ? ", String.valueOf(ConstantManager.LOGIN_IN)).find(UserAccount.class);
        if (null != userAccounts && userAccounts.size() > 0) {
            return userAccounts.get(0).getToken();
        }
        return null;
    }

    /**
     * 获取App上最后一次登录的用户
     *
     * @return
     */
    public synchronized UserAccount getLastLoginUserAccount() {
        List<UserAccount> userAccounts = DataSupport.select("phone", "password").order(" loginTime desc ").find(UserAccount.class);
        if (null != userAccounts && userAccounts.size() > 0) {
            return userAccounts.get(0);
        }
        return null;
    }

    /**
     * 根据用户ID获取用户对象
     *
     * @param userId
     * @return
     */
    public synchronized UserAccount findAccountByUserId(String userId) {
        List<UserAccount> persons = DataSupport.where("userId = ? order by loginStatus desc", userId).find(UserAccount.class);
        LogUtils.i("persons count:" + persons.size());
        if (persons == null || persons.size() == 0) {
            return null;
        } else {
            for (int i = 1; i < persons.size(); i++) {
                persons.get(i).delete();
            }
        }
        return persons.get(0);
    }
}